package cn.org.xuanguang.kepler.hormos.rdb.dml.operator.update;

import cn.org.xuanguang.kepler.hormos.rdb.dml.operator.DmlOperator;
import cn.org.xuanguang.kepler.hormos.rdb.dsl.execute.Delete;
import cn.org.xuanguang.kepler.hormos.rdb.dsl.param.Term;
import cn.org.xuanguang.kepler.hormos.rdb.dsl.sql.SqlRequest;
import cn.org.xuanguang.kepler.hormos.rdb.executor.SyncSqlExecutor;
import cn.org.xuanguang.kepler.hormos.rdb.plugin.DmlSQLBuilder;

import java.util.Arrays;
import java.util.Collection;

public class UpdateOperator implements DmlOperator<UpdateOperatorResulet> {
    // SyncSqlExecutor用于同步执行SQL命令
    private SyncSqlExecutor syncSqlExecutor;

    // dailatype用于指定数据库类型，影响数据库操作的执行方式
    private String dailatype;
    /**
     * 入参
     */
    UpdateOperatorParameter parameter;

    /**
     * 结果
     *
     * @return
     */
    UpdateOperatorResulet result = new UpdateOperatorResulet();

    public UpdateOperator(SyncSqlExecutor syncSqlExecutor, String dailatype, UpdateOperatorParameter updateOperatorParameter) {
        this.syncSqlExecutor = syncSqlExecutor;
        this.dailatype = dailatype;
        this.parameter = updateOperatorParameter;

    }

    public static UpdateOperator of(SyncSqlExecutor syncSqlExecutor, String dailatype, UpdateOperatorParameter updateOperatorParameter) {
        return new UpdateOperator(syncSqlExecutor, dailatype, updateOperatorParameter);
    }

    public UpdateOperator table(String tableName) {
        parameter.setTableName(tableName);
        return this;
    }

    /**
     * 添加需要插入的列集合。
     *
     * @param columns 要添加的列的集合，不可为null。
     * @return 返回当前UpdateOperator实例，允许链式调用。
     */
    public UpdateOperator columns(Collection<String> columns) {
        parameter.getColumns().addAll(columns);
        return this;
    }

    public UpdateOperator columns(String... columns) {
        parameter.getColumns().addAll(Arrays.asList(columns));
        return this;
    }

    /**
     * 向UpdateOperator实例添加一组值。
     * 这个方法允许通过收集对象的方式一次性添加多个值到操作符的参数中。
     *
     * @param values 需要被添加到操作符中的值的集合。集合中的元素类型为Object，允许包含任意类型的值。
     * @return 返回当前UpdateOperator实例，允许链式调用。
     */
    public UpdateOperator values(Collection<Object> values) {
        parameter.getValues().addAll(values);
        return this;
    }

    public UpdateOperator values(Object... values) {
        parameter.getValues().addAll(Arrays.asList(values));
        return this;
    }

    // 查询条件
    public UpdateOperator where(Delete delete) {
        parameter.getTerms().addAll(delete.getParam().getTerms());
        return this;
    }

    public UpdateOperator where(Collection<? extends Term> terms) {
        parameter.getTerms().addAll(terms);
        return this;
    }

    public UpdateOperator and(String column, String termType, Object value) {
        parameter.getTerms().addAll(Delete.of().and(column, termType, value).getParam().getTerms());
        return this;
    }

    public UpdateOperator or(String column, String termType, Object value) {
        parameter.getTerms().addAll(Delete.of().or(column, termType, value).getParam().getTerms());
        return this;
    }

    /**
     * 获取sql
     *
     * @return
     */
    @Override
    public SqlRequest getSql() {
        // 获取sql
        return DmlSQLBuilder.of(dailatype).buildUpdate(parameter);

    }

    @Override
    public UpdateOperatorResulet execute() {
        int updateed = syncSqlExecutor.update(getSql());
        result.setUpdated(updateed);
        return result.getResult();
    }
}
